﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using blacksoft.Models;
using blacksoft.Constantes;

namespace blacksoft.Controllers
{
    public class IncidenteController : Controller
    {
        private inf245travelbusEntities db = new inf245travelbusEntities();

        private ActionResult ValidarPermiso()
        {
            //NO ESTOY LOGUEADO EN EL SISTEMA
            if (Session["Permisos"] == null)
            {
                TempData["LogueatePrimero"] = SystemField.NO_LOGUEADO;
                return RedirectToAction("Index", "ValidarLogin");
            }
            //ESTOY LOGUEADO PERO NO TENGO PERMISO PARA REALIZAR ESTA ACCION
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.ADMINISTRACION))
            {
                TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                return RedirectToAction("Index", "MainPageEmployes");
            }
            return null;
        }

        private class ItemListaChoferes
        {
            public int id { get; set; }
            public string nombre { get; set; }

            public ItemListaChoferes(int id, string nombre)
            {
                this.id = id;
                this.nombre = nombre;
            }
        }
        private List<ItemListaChoferes> obtenerChoferes()
        {
            var choferQry = from c in db.Persona
                            where c.Estado != "AN" && c.CargoPersonal == "Chofer"
                            select c;
            List<ItemListaChoferes> choferLst = new List<ItemListaChoferes>();
            foreach (var chofer in choferQry)
            {
                choferLst.Add(new ItemListaChoferes(chofer.IDPersona, chofer.DNI + " " + chofer.Nombre + " " + chofer.ApellidoPaterno + " " +
                    chofer.ApellidoMaterno));
            }
            return choferLst;
        }

        private List<ItemListaChoferes> filtrarChoferes()
        {
            var choferQry = from c in db.Persona
                            where c.Estado != "AN" && c.CargoPersonal == "Chofer"
                            select c;
            List<ItemListaChoferes> choferLst = new List<ItemListaChoferes>();
            foreach (var chofer in choferQry)
            {
                choferLst.Add(new ItemListaChoferes(chofer.IDPersona, chofer.Nombre + " " + chofer.ApellidoPaterno + " " + chofer.ApellidoMaterno));
            }
            return choferLst;
        }

        private class ItemListaViajes
        {
            public int id_viaje { get; set; }
            public string ruta { get; set; }

            public ItemListaViajes(int id_viaje, string ruta)
            {
                this.id_viaje = id_viaje;
                this.ruta = ruta;
            }
        }
        private List<ItemListaViajes> obtenerViajes()
        {
            int id_terminal = (int)Session["IDTerminal"];
            string destino = db.Terminal.Single(t=>t.IDTerminal==id_terminal).Nombre;
            var viajeQry = from v in db.ProgramacionViaje
                           where v.Estado != "AN" && v.Ruta_x_UnidadTransporte.Ruta.Estado != "AN" 
                           && v.Ruta_x_UnidadTransporte.UnidadTransporte.Estado!="AN"
                           select v;
            //Si NO tiene permiso Global, solo se crean incidentes sobre viajes relacionados a la terminal
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL))
            {
                viajeQry = viajeQry.Where(v=>v.Ruta_x_UnidadTransporte.Ruta.IDTerminal == id_terminal 
                    || v.Ruta_x_UnidadTransporte.Ruta.TerminalDestino == destino);
            }
            
            List<ItemListaViajes> viajeLst = new List<ItemListaViajes>();
            foreach (var viaje in viajeQry)
            {
                viajeLst.Add(new ItemListaViajes(viaje.IDProgramacionViaje, viaje.IDProgramacionViaje + " " + viaje.Ruta_x_UnidadTransporte.Ruta.Origen +
                    "-" + viaje.Ruta_x_UnidadTransporte.Ruta.Destino));
            }
            return viajeLst;
        }

        // GET: /Incidente/
        public ActionResult Index(string unidad, string chofer, string lugar, string viaje, string fecha_desde, string fecha_hasta)
        {
            ActionResult permiso = ValidarPermiso();
            if (permiso != null) return permiso;
            //Query de la lista de choferes registrados para filtrar
            ViewBag.chofer = new SelectList(filtrarChoferes(), "id", "nombre");
            //Query de la lista de unidades registradas para filtrar
            ViewBag.unidad = new SelectList(db.UnidadTransporte.Where(u => u.Estado != "AN").OrderBy(u => u.NumeroPlaca), "IDUnidadTransporte", "NumeroPlaca");

            var incidente = db.Incidente.Include(i => i.ProgramacionViaje).Include(i => i.Persona).Where(i=>i.ProgramacionViaje.Ruta_x_UnidadTransporte.UnidadTransporte.Estado!="AN" 
                && i.ProgramacionViaje.Ruta_x_UnidadTransporte.Ruta.Estado!="AN");

            //Si NO tiene permiso Global
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL))
            {
                int id_terminal = (int)Session["IDTerminal"];
                string destino = db.Terminal.Single(t => t.IDTerminal == id_terminal).Nombre;
                //Solo se muestran los registros de la terminal
                incidente = incidente.Where(i => i.ProgramacionViaje.Ruta_x_UnidadTransporte.Ruta.IDTerminal == id_terminal || i.ProgramacionViaje.Ruta_x_UnidadTransporte.Ruta.TerminalDestino == destino);
            }
            //Filtro del listado
            if (!String.IsNullOrEmpty(viaje))
            {
                incidente = incidente.Where(i => i.IDProgramacionViaje.ToString() == viaje);
            }
            if (!String.IsNullOrEmpty(unidad))
            {
                incidente = incidente.Where(i => i.ProgramacionViaje.Ruta_x_UnidadTransporte.UnidadTransporte.IDUnidadTransporte.ToString() == unidad);
            }
            if (!String.IsNullOrEmpty(chofer))
            {
                incidente = incidente.Where(i => i.Persona.IDPersona.ToString() == chofer);
            }
            if (!String.IsNullOrEmpty(lugar))
            {
                incidente = incidente.Where(i => i.Lugar.Contains(lugar));
            }
            try
            {
                if (!String.IsNullOrEmpty(fecha_desde))
                {
                    DateTime fecha = Convert.ToDateTime(fecha_desde);
                    incidente = incidente.Where(i => (i.Fecha.Year > fecha.Year) || (i.Fecha.Year == fecha.Year && i.Fecha.Month > fecha.Month)
                        || (i.Fecha.Year == fecha.Year && i.Fecha.Month == fecha.Month && i.Fecha.Day > fecha.Day)
                        || (i.Fecha.Year == fecha.Year && i.Fecha.Month == fecha.Month && i.Fecha.Day == fecha.Day && i.Fecha.Hour > fecha.Hour)
                        || (i.Fecha.Year == fecha.Year && i.Fecha.Month == fecha.Month && i.Fecha.Day == fecha.Day && i.Fecha.Hour == fecha.Hour && i.Fecha.Minute > fecha.Minute)
                        || (i.Fecha.Year == fecha.Year && i.Fecha.Month == fecha.Month && i.Fecha.Day == fecha.Day && i.Fecha.Hour == fecha.Hour && i.Fecha.Minute == fecha.Minute && i.Fecha.Second >= i.Fecha.Second));
                }
                if (!String.IsNullOrEmpty(fecha_hasta))
                {
                    DateTime fecha = Convert.ToDateTime(fecha_hasta);
                    incidente = incidente.Where(i => (i.Fecha.Year < fecha.Year) || (i.Fecha.Year == fecha.Year && i.Fecha.Month < fecha.Month)
                        || (i.Fecha.Year == fecha.Year && i.Fecha.Month == fecha.Month && i.Fecha.Day < fecha.Day)
                        || (i.Fecha.Year == fecha.Year && i.Fecha.Month == fecha.Month && i.Fecha.Day == fecha.Day && i.Fecha.Hour < fecha.Hour)
                        || (i.Fecha.Year == fecha.Year && i.Fecha.Month == fecha.Month && i.Fecha.Day == fecha.Day && i.Fecha.Hour == fecha.Hour && i.Fecha.Minute < fecha.Minute)
                        || (i.Fecha.Year == fecha.Year && i.Fecha.Month == fecha.Month && i.Fecha.Day == fecha.Day && i.Fecha.Hour == fecha.Hour && i.Fecha.Minute == fecha.Minute && i.Fecha.Second <= i.Fecha.Second));
                }
            }
            catch
            {
                TempData["index"] = "Ocurrió un error inesperado. Intentelo otra vez.";
                return RedirectToAction("Index");
            }
            return View(incidente.ToList());
        }

        // GET: /Incidente/Details/5
        public ActionResult Details(int? id)
        {
            ActionResult permiso = ValidarPermiso();
            if (permiso != null) return permiso;
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Incidente incidente = db.Incidente.Find(id);
            if (incidente == null)
            {
                return HttpNotFound();
            }
            return View(incidente);
        }

        // GET: /Incidente/Create
        public ActionResult Create()
        {
            ActionResult permiso = ValidarPermiso();
            if (permiso != null) return permiso;
            try
            {
                ViewBag.IDProgramacionViaje = new SelectList(obtenerViajes(), "id_viaje", "ruta");
                ViewBag.IDPersona = new SelectList(obtenerChoferes(), "id", "nombre");
            }
            catch
            {
                TempData["index"] = "Ocurrió un error inesperado. Intentelo otra vez.";
                return RedirectToAction("Index");
            }
            return View();
        }

        // POST: /Incidente/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "IDIncidente,Fecha,Lugar,Descripcion,AccionTomada,IDProgramacionViaje,IDPersona")] Incidente incidente)
        {
            ActionResult permiso = ValidarPermiso();
            if (permiso != null) return permiso;

            //NO se pueden registrar incidentes con fecha futura
            if (incidente.Fecha.CompareTo(DateTime.Now) > 0)
            {
                TempData["index"] = "No puede registrar un incidente con fecha a futuro.";
                try
                {
                    ViewBag.IDProgramacionViaje = new SelectList(obtenerViajes(), "id_viaje", "ruta", incidente.IDProgramacionViaje);
                    ViewBag.IDPersona = new SelectList(obtenerChoferes(), "id", "nombre", incidente.IDPersona);
                }
                catch
                {
                    TempData["index"] = "Ocurrió un error inesperado, NO se pudo registrar el incidente. Intentelo otra vez.";
                    return RedirectToAction("Index");
                }
                return View(incidente);
            }
            try
            {
                if (ModelState.IsValid)
                {
                    db.Incidente.Add(incidente);
                    db.SaveChanges();
                    TempData["create_success"] = "Incidente registrado correctamente.";
                    return RedirectToAction("Index");
                }
            }
            catch
            {
                TempData["create"] = "Ocurrió un error inesperado, NO se pudo registrar el incidente. Intentelo otra vez.";
            }
            try
            {
                ViewBag.IDProgramacionViaje = new SelectList(obtenerViajes(), "id_viaje", "ruta", incidente.IDProgramacionViaje);
                ViewBag.IDPersona = new SelectList(obtenerChoferes(), "id", "nombre", incidente.IDPersona);
            }
            catch
            {
                TempData["index"] = "Ocurrió un error inesperado, NO se pudo registrar el incidente. Intentelo otra vez.";
                return RedirectToAction("Index");
            }
            return View(incidente);
        }

        // GET: /Incidente/Edit/5
        public ActionResult Edit(int? id)
        {
            ActionResult permiso = ValidarPermiso();
            if (permiso != null) return permiso;
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Incidente incidente = db.Incidente.Find(id);
            if (incidente == null)
            {
                return HttpNotFound();
            }
            try
            {
                ViewBag.IDProgramacionViaje = new SelectList(obtenerViajes(), "id_viaje", "ruta", incidente.IDProgramacionViaje);
                ViewBag.IDPersona = new SelectList(obtenerChoferes(), "id", "nombre", incidente.IDPersona);
            }
            catch
            {
                TempData["index"] = "Ocurrió un error inesperado. Intentelo otra vez.";
                return RedirectToAction("Index");
            }
            return View(incidente);
        }

        // POST: /Incidente/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "IDIncidente,Fecha,Lugar,Descripcion,AccionTomada,IDProgramacionViaje,IDPersona")] Incidente incidente)
        {
            ActionResult permiso = ValidarPermiso();
            if (permiso != null) return permiso;

            //NO se pueden registrar incidentes con fecha futura
            if (incidente.Fecha.CompareTo(DateTime.Now) > 0)
            {
                TempData["index"] = "No puede registrar un incidente con fecha a futuro.";
                try
                {
                    ViewBag.IDProgramacionViaje = new SelectList(obtenerViajes(), "id_viaje", "ruta", incidente.IDProgramacionViaje);
                    ViewBag.IDPersona = new SelectList(obtenerChoferes(), "id", "nombre", incidente.IDPersona);
                }
                catch
                {
                    TempData["index"] = "Ocurrió un error inesperado, NO se pudo registrar el incidente. Intentelo otra vez.";
                    return RedirectToAction("Index");
                }
                return View(incidente);
            }
            try
            {
                if (ModelState.IsValid)
                {
                    db.Entry(incidente).State = EntityState.Modified;
                    db.SaveChanges();
                    TempData["edit_success"] = "Incidente modificado correctamente.";
                    return RedirectToAction("Index");
                }
            }
            catch
            {
                TempData["edit"] = "Ocurrió un error inesperado, NO se pudieron guardar los cambios al incidente. Intentelo otra vez.";
            }
            try
            {
                ViewBag.IDProgramacionViaje = new SelectList(obtenerViajes(), "id_viaje", "ruta", incidente.IDProgramacionViaje);
                ViewBag.IDPersona = new SelectList(obtenerChoferes(), "id", "nombre", incidente.IDPersona);
            }
            catch
            {
                TempData["index"] = "Ocurrió un error inesperado, NO se pudieron guardar los cambios al incidente. Intentelo otra vez.";
                return RedirectToAction("Index");
            }
            return View(incidente);
        }

        // GET: /Incidente/Delete/5
        public ActionResult Delete(int? id, bool? saveChangesError = false)
        {
            ActionResult permiso = ValidarPermiso();
            if (permiso != null) return permiso;
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            if (saveChangesError.GetValueOrDefault())
            {
                TempData["delete"] = "NO se pudo eliminar el registro.";
            }
            Incidente incidente = db.Incidente.Find(id);
            if (incidente == null)
            {
                return HttpNotFound();
            }
            return View(incidente);
        }

        // POST: /Incidente/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            ActionResult permiso = ValidarPermiso();
            if (permiso != null) return permiso;
            try
            {
                Incidente incidente = db.Incidente.Find(id);
                db.Incidente.Remove(incidente);
                db.SaveChanges();
            }
            catch
            {
                return RedirectToAction("Delete", new { id = id, saveChangesError = true });
            }
            TempData["delete_success"] = "Incidente eliminado correctamente.";
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
